package css.sword.base;

import com.fasterxml.jackson.databind.ObjectMapper;
import css.sword.util.StringUtils;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static org.springframework.util.StringUtils.getFilename;

/**
 * @author zhuxiaomeng
 * @date 2017/12/19.
 * @email 154040976@qq.com
 */
public abstract class BaseController<T> {

    protected static ObjectMapper mapper = new ObjectMapper();

    public static final Map<String, String> EXT_MAPS = new HashMap<>();

    private void initExt() {
        // image
        EXT_MAPS.put("png", "image/png");
        EXT_MAPS.put("gif", "image/gif");
        EXT_MAPS.put("bmp", "image/bmp");
        EXT_MAPS.put("ico", "image/x-ico");
        EXT_MAPS.put("jpeg", "image/jpeg");
        EXT_MAPS.put("jpg", "image/jpeg");
        // 压缩文件
        EXT_MAPS.put("zip", "application/zip");
        EXT_MAPS.put("rar", "application/x-rar");
        // doc
        EXT_MAPS.put("pdf", "application/pdf");
        EXT_MAPS.put("ppt", "application/vnd.ms-powerpoint");
        EXT_MAPS.put("xls", "application/vnd.ms-excel");
        EXT_MAPS.put("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        EXT_MAPS.put("pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation");
        EXT_MAPS.put("doc", "application/msword");
        EXT_MAPS.put("doc", "application/wps-office.doc");
        EXT_MAPS.put("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        EXT_MAPS.put("txt", "text/plain");
        // 音频
        EXT_MAPS.put("mp4", "video/mp4");
        EXT_MAPS.put("flv", "video/x-flv");

    }

//    public static String getToken(String filepath, String httpSecretKey){
//        // unix seconds
//        int ts = (int) Instant.now().getEpochSecond();
//        // token
//        String token = "null";
//        try {
//            token = ProtoCommon.getToken(getFilename(filepath), ts, httpSecretKey);
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//        } catch (NoSuchAlgorithmException e) {
//            e.printStackTrace();
//        } catch (MyException e) {
//            e.printStackTrace();
//        }
//
//        StringBuilder sb = new StringBuilder();
//        sb.append("token=").append(token);
//        sb.append("&ts=").append(ts);
//
//        return sb.toString();
//    }

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Date.class, new CustomDateEditor(
                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true));
        binder.registerCustomEditor(Date.class, new CustomDateEditor(
                new SimpleDateFormat("yyyy-MM-dd"), true));
        binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
    }

//    @ExceptionHandler({UnauthorizedException.class, AuthorizationException.class})
//    public String authorizationException(HttpServletRequest request, HttpServletResponse response) {
//        if (isAjaxRequest(request)) {
//            Map<String, Object> map = Maps.newHashMap();
//            map.put("code", "403");
//            map.put("message", "无权限");
//            return JSON.toJSONString(map);
//        } else {
//            String message = "权限不足";
//            try {
//                message = URLEncoder.encode(message, "utf-8");
//            } catch (UnsupportedEncodingException e) {
//                log.error("BaseController：" + e.getMessage());
//                e.printStackTrace();
//            }
//            return "redirect:/error/403?message=" + message;
//        }
//    }

    private static boolean isAjaxRequest(HttpServletRequest request) {
        String requestedWith = request.getHeader("x-requested-with");
        return requestedWith != null && requestedWith.equalsIgnoreCase("XMLHttpRequest");
    }

    /**
     * 货币格式化
     *
     * @param amount
     *            金额
     * @param showSign
     *            显示标志
     * @param showUnit
     *            显示单位
     * @return 货币格式化
     */
    protected String currency(BigDecimal amount, String showSign, String showUnit) {
        String price = amount.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
        if (StringUtils.isNotBlank(showSign)) {
            price = showSign + price;
        }
        if (StringUtils.isNotBlank(showUnit)) {
            price += showUnit;
        }
        return price;
    }

    /**
     * 添加日志
     *
     * @param content
     *            内容
     */
    protected void addLog(String content) {
        if (content != null) {
            RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
            requestAttributes.setAttribute("LOG.CONTENT", content, RequestAttributes.SCOPE_REQUEST);
        }
    }

    public static String getIp(HttpServletRequest request){
        String ip=request.getHeader("x-forwarded-for");
        if(ip==null || ip.length()==0 || "unknown".equalsIgnoreCase(ip)){
            ip=request.getHeader("Proxy-Client-IP");
        }
        if(ip==null || ip.length()==0 || "unknown".equalsIgnoreCase(ip)){
            ip=request.getHeader("WL-Proxy-Client-IP");
        }
        if(ip==null || ip.length()==0 || "unknown".equalsIgnoreCase(ip)){
            ip=request.getHeader("X-Real-IP");
        }
        if(ip==null || ip.length()==0 || "unknown".equalsIgnoreCase(ip)){
            ip=request.getRemoteAddr();
        }
        return ip;
    }

}
